﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BrokerBase.Lib.Core;
using BrokerBase.Lib.Metadata;
using BrokerBase.Lib.Base;
using BrokerBase.Lib.Company;
using BrokerBase.Lib.Person;
using BrokerBase.Lib.Dynamic;
using BrokerBase.Lib.Policy;
using BrokerBase.Lib.Product;
using System.Reflection;
using System.Resources;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

namespace BrokerBase.Lib.Dynamic
{
    public class DynamicCode
    {

        public Func<IPolicy, object> CreateFunc(string express)
        {
            string className="TmpClass100";
            string code=CodeBuild(className,express);

            string ss = Guid.NewGuid().ToString();

            CSharpCodeProvider provider = new CSharpCodeProvider();

            CompilerParameters par = new CompilerParameters();  
            par.ReferencedAssemblies.Add("System.dll");
            par.ReferencedAssemblies.Add("System.Core.dll");
            par.ReferencedAssemblies.Add("mscorlib.dll");
            par.ReferencedAssemblies.Add("BrokerBase.Lib.dll");

            par.GenerateExecutable = false;
            par.GenerateInMemory = true;

            CompilerResults compile = provider.CompileAssemblyFromSource(par, new string[]{ code });

            if(compile.Errors.HasErrors)
            {
                foreach (CompilerError e in compile.Errors)
                {

                    Console.WriteLine(e.ErrorText);
                }
            }

            Assembly assembly=compile.CompiledAssembly;

            IEvaluation evl=(IEvaluation)assembly.CreateInstance("BrokerBase.Lib.Dynamic."+className);

            return evl.Eval;
        }

        private string  CodeBuild(string className,string express)
        {
            Assembly assembly;
            ResourceManager rmManager;

            assembly = Assembly.GetExecutingAssembly();
            rmManager = new ResourceManager("BrokerBase.Lib.DynamicCodeResource", assembly);
            string s = rmManager.GetString("UsingCode");

            StringBuilder code = new StringBuilder(5000);

            code.Append(s);
            code.Append(Environment.NewLine);

            code.Append("namespace BrokerBase.Lib.Dynamic");
            code.Append(Environment.NewLine);
            code.Append("{");
            code.Append("   public class "+className+":IEvaluation");
            code.Append(Environment.NewLine);
            code.Append("   {");
            code.Append(Environment.NewLine);
            code.Append("       public object Eval(IPolicy policy)");
            code.Append(Environment.NewLine);
            code.Append("       {");
            code.Append(Environment.NewLine);
            code.Append("           " + "return " + express+";");
            code.Append(Environment.NewLine);
            code.Append("       }");
            code.Append(Environment.NewLine);
            code.Append("   }");
            code.Append(Environment.NewLine);
            code.Append("}");

            return code.ToString();
        }


    }
}
